Skip to content

SQLmap in action

测试自己的机器上的项目可以随便用,测试他人的服务或线上项目时避免使用(谨慎使用)os系列参数

准备阶段

  1. 找有漏洞的接口
    • 使用AWVS等漏扫工具对项目进行扫描,找到问题的接口;
    • 通过其他途径,找到可能存在SQL注入问题的接口;
  2. 安装SQLmap工具
    • SQLmap官网 获取(推荐开发同事使用该方式);
    • 使用Kali系统(较重,仅推荐长期进行渗透测试的同事使用);

环境说明

keyvalueremark
目标接口http://192.168.154.1:1993/sql?ok=1通过/sql接口的ok参数,将payload传到数据库
数据库Postgres 13

测试示例

  1. 使用--url 指定接口url
  2. 当前目标接口没有登录验证,如果有登录验证,需要使用--cookie 传递cookie值
  3. 如果知道目标服务使用的是什么数据库,可以通过--dbms 指定只用这种数据库的payload
  4. 假设接口有多个参数(ok、no),但只有"ok"参数可以被利用,可以使用-p 参数指定利用参数
  5. 嫌麻烦可以试试--wizard参数,这个参数会引导用户进行测试,适合新手或忘了SQLmap怎么使用的用户,这里就不演示了。

假设当前环境可用cookie值为"xiaolongtest",已知"ok"参数可被利用,不知道后端数据库是什么类型,可以这样操作,获取后端数据库类型。

shell
sqlmap --cookie xiaolongtest --url "http://192.168.154.1:1993/sql?ok=1&no=2" -D DB -p ok

探测数据库类型 如果指定了错误(无法被利用)的参数,则不会有结果。 参数不可利用

对于以发现问题为目的的开发人员到了这里,就可以了,因为即使是盲注,没能直接返回数据库的内容,但也是恶意用户传入的命令被执行了,不死心可以用--tables让sqlmap返回所有库表。

shell
sqlmap --cookie xiaolongtest --url "http://192.168.154.1:1993/sql?ok=1&no=2" --dbms=PostgreSQL --tables

库表信息

库表信息被打印出来,就可以完全死心了,这个接口肯定需要修复。
当业务复杂,不确定哪个参数会被利用,就不要使用-p参数,url中的参数尽量写全,这样在测试过程中SQLmap会检测所有参数,只是执行过程中,SQLmap会要求交互,有交互时根据提示进行操作即可。

自助

不会使用时,可以执行--help或man命令,查看帮助信息
--help命令

shell
sqlmap --help

help命令 man命令

shell
man sqlmap

man命令

示例代码

目录结构

mermaid
graph LR
subgraph 目录结构
A[root]---B[src]
A---C[go.mod]
B---D[application.go]
end

application.go

go
package main

import (
    "container/list"
    "database/sql"
    "log"

    "github.com/gin-gonic/gin"
    _ "github.com/lib/pq"
)

func main() {
    connStr := "dbname=akmc user=sun password=1 host=127.0.0.1 port=5432 connect_timeout=5 sslmode=disable"
    db, err := sql.Open("postgres", connStr)
    if nil != err {
        log.Panicln(err)
    }
    r := gin.Default()
    r.GET("/sql", func(c *gin.Context) {
        var okValue = "SELECT guid FROM ep WHERE guid = '" + c.Request.URL.Query().Get("ok") + "'"
        log.Println(okValue)
        rsInDb, err := db.Query(okValue)
        if nil != err {
            log.Println(err)
        }
        var resultList list.List
        for rsInDb.Next() {
            var value string
            _ = rsInDb.Scan(&value)
            var row = make(map[string]interface{})
            row["guid"] = value
            resultList.PushBack(row)
        }
        var result []interface{}
        for e := resultList.Front(); e != nil; e = e.Next() {
            // do something with e.Value
            result = append(result, e.Value)
        }
        c.JSON(200, gin.H{
            "message": result,
        })
    })
    r.Run("0.0.0.0:1993")
}

go.mod

go
module sqlmap

go 1.16

require (
    github.com/gin-gonic/gin v1.7.4 // indirect
    github.com/go-playground/validator/v10 v10.9.0 // indirect
    github.com/golang/protobuf v1.5.2 // indirect
    github.com/json-iterator/go v1.1.12 // indirect
    github.com/lib/pq v1.10.3 // indirect
    github.com/mattn/go-isatty v0.0.14 // indirect
    github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
    github.com/ugorji/go v1.2.6 // indirect
    golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
    golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
    golang.org/x/text v0.3.7 // indirect
    google.golang.org/protobuf v1.27.1 // indirect
    gopkg.in/yaml.v2 v2.4.0 // indirect
)